package com.bkgy.controller.rollPosImage.service.impl;

import com.alibaba.excel.util.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bkgy.controller.rollPosImage.dao.RollInspectionDAO;
import com.bkgy.controller.rollPosImage.dao.RollLogDAO;
import com.bkgy.controller.rollPosImage.dao.RollPosImageDAO;
import com.bkgy.controller.rollPosImage.entity.*;
import com.bkgy.controller.rollPosImage.service.RollPosImageService;
import com.bkgy.sys.common.entity.ResultData;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.CompletableFuture;

@Service
@Slf4j
public class RollPosImageServiceImpl implements RollPosImageService {

    @Autowired
    private RollPosImageDAO rollPosImageDAO;
    @Autowired
    private RollInspectionDAO rollInspectionDAO;
    @Autowired
    private RollLogDAO rollLogDAO;

    @Override
    public ResultData getRollByRequestInfo(RollPosImageRequest request) {
        try {
            if (request == null) {
                return ResultData.ResultDataFaultSelf("请求参数不能为空", null);
            }

            // 设置默认分页参数
            if (request.getPageIndex() == null || request.getPageIndex() < 1) {
                request.setPageIndex(1);
            }
            if (request.getPageSize() == null || request.getPageSize() < 1) {
                request.setPageSize(10);
            }

            RollPosImage rollPosImage = rollPosImageDAO.getRollByRequestInfo(request);
            if (rollPosImage == null) {
                return ResultData.ResultDataFaultSelf("未找到对应的工艺辊信息", null);
            }

            // 创建两个独立的分页对象，用于不同的查询
            Page<?> inspectionPage = new Page<>(
                    request.getCheckPage() != null && request.getCheckPage() > 0
                            ? request.getCheckPage() : request.getPageIndex(),
                    request.getCheckPageSize() != null && request.getCheckPageSize() > 0
                            ? request.getCheckPageSize() : request.getPageSize()
            );

            Page<?> logPage = new Page<>(
                    request.getChangePage() != null && request.getChangePage() > 0
                            ? request.getChangePage() : request.getPageIndex(),
                    request.getChangePageSize() != null && request.getChangePageSize() > 0
                            ? request.getChangePageSize() : request.getPageSize()
            );

            CompletableFuture<List<RollInspection>> inspectionsFuture = CompletableFuture.supplyAsync(() ->
                    rollInspectionDAO.findInspectionList(inspectionPage, request));

            CompletableFuture<Integer> inspectionCountFuture = CompletableFuture.supplyAsync(() ->
                    rollInspectionDAO.findInspectionCount(request));

            CompletableFuture<List<RollLog>> changeLogsFuture = CompletableFuture.supplyAsync(() ->
                    rollLogDAO.selectList(logPage, request));

            CompletableFuture<Integer> changeLogCountFuture = CompletableFuture.supplyAsync(() ->
                    rollLogDAO.selectCount(request));

            try {
                CompletableFuture.allOf(inspectionsFuture, inspectionCountFuture,
                        changeLogsFuture, changeLogCountFuture).join();
            } catch (Exception e) {
                log.error("Async task failed with root cause:", e);
                throw e; // 或返回错误响应
            }

            RollPosImageResponse response = new RollPosImageResponse();
            response.setRollPosImage(rollPosImage);
            response.setRollInspectionList(inspectionsFuture.get());
            response.setInspectionCount(inspectionCountFuture.get());
            response.setRollLogs(changeLogsFuture.get());
            response.setChangeLogCount(changeLogCountFuture.get());

            return ResultData.ResultDataSuccess(response);

        } catch (Exception e) {
            return ResultData.ResultDataFaultGd("系统繁忙，请稍后再试", null);
        }
    }

    @Override
    public ResultData getRollListByRGroup(RollPosImageRequest request) {
        // 1. 参数校验
        if (request == null || StringUtils.isBlank(request.getLine()) || StringUtils.isBlank(request.getRGroup())) {
            return ResultData.ResultDataFaultSelf("产线和机组参数不能为空", null);
        }

        try {
            Date currentDate = new Date();
            log.info("开始查询机组工艺辊数据，产线: {}, 机组: {}", request.getLine(), request.getRGroup());

            // 2. 获取点检信息列表
            List<RollPosImage> checkList = rollPosImageDAO.getRollListByRGroup(request);
            log.debug("获取到点检信息记录数: {}", checkList.size());

            // 3. 获取更换信息列表
            RollPosImageRequest changeRequest = new RollPosImageRequest();
            changeRequest.setRGroup(request.getRGroup());
            changeRequest.setLine(request.getLine());
            changeRequest.setStatus(3); // 3表示需要更换的状态
            List<RollPosImage> changeList = rollPosImageDAO.getRollListByRGroup(changeRequest);
            log.debug("获取到更换信息记录数: {}", changeList.size());

            // 4. 筛选待更换的辊
            List<RollPosImage> pendingChangeList = filterPendingChangeItems(changeList, currentDate);

            // 5. 筛选待点检的辊
            List<RollPosImage> pendingCheckList = filterPendingCheckItems(checkList, currentDate);

            // 6. 构建返回结果
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("pendingChangeList", pendingChangeList); // 待更换列表
            resultMap.put("pendingChangeCount", pendingChangeList.size()); // 待更换数量
            resultMap.put("pendingCheckList", pendingCheckList); // 待点检列表
            resultMap.put("pendingCheckCount", pendingCheckList.size()); // 待点检数量

            log.info("查询完成，待更换: {}个, 待点检: {}个",
                    pendingChangeList.size(), pendingCheckList.size());
            return ResultData.ResultDataSuccess(resultMap);

        } catch (NumberFormatException e) {
            log.error("数字格式转换异常", e);
            return ResultData.ResultDataFaultSelf("数据格式错误，请检查周期设置", null);
        } catch (Exception e) {
            log.error("获取机组工艺辊列表异常 - 产线: {}, 机组: {}",
                    request.getLine(), request.getRGroup(), e);
            return ResultData.ResultDataFaultGd("系统繁忙，请稍后再试", null);
        }
    }

    /**
     * 筛选待更换的工艺辊
     * @param changeList 更换历史列表
     * @param currentDate 当前日期
     * @return 待更换的工艺辊列表
     */
    private List<RollPosImage> filterPendingChangeItems(List<RollPosImage> changeList, Date currentDate) {
        List<RollPosImage> pendingList = new ArrayList<>();

        changeList.forEach(item -> {
            try {
                // 跳过无效记录
                if (item == null || item.getFirstTime() == null) {
                    return;
                }

                // 确定基准时间（优先使用launchDate）
                Date baseDate = Optional.ofNullable(item.getLaunchDate())
                        .orElse(item.getFirstTime());

                // 安全获取更换周期
                int changeCycle = NumberUtils.toInt(item.getChangeCycle(), 0);

                // 计算到期时间
                Date dueDate = calculateDueDate(baseDate, changeCycle);

                // 判断是否需要更换
                if (dueDate.before(currentDate)) {
                    pendingList.add(item);
                }
            } catch (Exception e) {
                log.warn("处理更换记录异常，辊ID: {}", item.getId(), e);
            }
        });

        return pendingList;
    }

    /**
     * 筛选待点检的工艺辊
     * @param checkList 点检列表
     * @param currentDate 当前日期
     * @return 待点检的工艺辊列表
     */
    private List<RollPosImage> filterPendingCheckItems(List<RollPosImage> checkList, Date currentDate) {
        List<RollPosImage> pendingList = new ArrayList<>();

        checkList.forEach(item -> {
            try {
                // 跳过无效记录
                if (item == null || item.getFirstTime() == null) {
                    return;
                }

                // 确定基准时间（新辊用firstTime，否则用launchDate）
                Date baseDate = (item.getStatus() != null && item.getStatus() == 1)
                        ? item.getFirstTime()
                        : Optional.ofNullable(item.getLaunchDate())
                        .orElse(item.getFirstTime());

                // 安全获取点检周期
                int checkCycle = NumberUtils.toInt(item.getCheckCycle(), 0);

                // 计算到期时间
                Date dueDate = calculateDueDate(baseDate, checkCycle);

                // 判断是否需要点检
                if (dueDate.before(currentDate)) {
                    pendingList.add(item);
                }
            } catch (Exception e) {
                log.warn("处理点检记录异常，辊ID: {}", item.getId(), e);
            }
        });

        return pendingList;
    }

    /**
     * 计算到期日期
     * @param baseDate 基准日期
     * @param daysToAdd 要添加的天数
     * @return 计算后的日期
     */
    private Date calculateDueDate(Date baseDate, int daysToAdd) {
        if (baseDate == null) {
            throw new IllegalArgumentException("基准日期不能为空");
        }

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(baseDate);
        calendar.add(Calendar.DAY_OF_YEAR, daysToAdd);
        return calendar.getTime();
    }
}